#include "util_texturemanager.h"
#include <fstream>
using namespace std;

/*******************************
*
*******************************/
void LJMUUtilTextureMgr::initialise(ID3D10Device* pdevice)
{
	this->_obj_dx10_device = pdevice;
}

/*******************************
*
*******************************/
ID3D10ShaderResourceView* LJMUUtilTextureMgr::createTex(wstring ptextureloc)
{
	// Has this texture already been created?
	for(size_t i = 0; i < _list_tex_rv.size(); ++i)
		if(_list_tex_cache[i] == ptextureloc)
			return _list_tex_rv[i];

	// If not, create it.
	ID3D10ShaderResourceView* trv = NULL;
	if(FAILED(D3DX10CreateShaderResourceViewFromFile(_obj_dx10_device, ptextureloc.c_str(), 0, 0, &trv, 0 )))
		return NULL;

	_list_tex_cache.push_back(ptextureloc);
	_list_tex_rv.push_back(trv);
	return trv;
}

/******************************
*
******************************/
ID3D10ShaderResourceView* LJMUUtilTextureMgr::createTexArray(wstring parrayid, const LJMUStringList& ptexnames)
{
	for(size_t i = 0; i < _list_tex_rv.size(); ++i)
		if( _list_tex_cache[i] == parrayid )
			return _list_tex_rv[i];

	UINT tarraycount = (UINT)ptexnames.size();

	vector<ID3D10Texture2D*> ttexlist(tarraycount, 0);
	for(UINT i = 0; i < tarraycount; ++i)
	{
		D3DX10_IMAGE_LOAD_INFO tloadinfo;
		tloadinfo.Width			= D3DX10_FROM_FILE;
        tloadinfo.Height		= D3DX10_FROM_FILE;
        tloadinfo.Depth			= D3DX10_FROM_FILE;
        tloadinfo.FirstMipLevel = 0;
        tloadinfo.MipLevels		= D3DX10_FROM_FILE;
        tloadinfo.Usage			= D3D10_USAGE_STAGING;
        tloadinfo.BindFlags		= 0;
        tloadinfo.CpuAccessFlags = D3D10_CPU_ACCESS_WRITE | D3D10_CPU_ACCESS_READ;
        tloadinfo.MiscFlags		= 0;
        tloadinfo.Format		= DXGI_FORMAT_R8G8B8A8_UNORM;
        tloadinfo.Filter		= D3DX10_FILTER_NONE;
        tloadinfo.MipFilter		= D3DX10_FILTER_NONE;
		tloadinfo.pSrcInfo		= 0;

        if(FAILED(D3DX10CreateTextureFromFile(_obj_dx10_device, ptexnames[i].c_str(),&tloadinfo, 0, (ID3D10Resource**)&ttexlist[i], 0)))
			return NULL;
	}

	D3D10_TEXTURE2D_DESC ttexdesc;
	ttexlist[0]->GetDesc(&ttexdesc);

	D3D10_TEXTURE2D_DESC ttexarraydesc;
	ttexarraydesc.Width              = ttexdesc.Width;
	ttexarraydesc.Height             = ttexdesc.Height;
	ttexarraydesc.MipLevels          = ttexdesc.MipLevels;
	ttexarraydesc.ArraySize          = tarraycount;
	ttexarraydesc.Format             = DXGI_FORMAT_R8G8B8A8_UNORM;
	ttexarraydesc.SampleDesc.Count   = 1;
	ttexarraydesc.SampleDesc.Quality = 0;
	ttexarraydesc.Usage              = D3D10_USAGE_DEFAULT;
	ttexarraydesc.BindFlags          = D3D10_BIND_SHADER_RESOURCE;
	ttexarraydesc.CPUAccessFlags     = 0;
	ttexarraydesc.MiscFlags          = 0;

	ID3D10Texture2D* ttexarray = 0;
	if(FAILED(_obj_dx10_device->CreateTexture2D( &ttexarraydesc, 0, &ttexarray)))
		return NULL;

	for(UINT i = 0; i < tarraycount; ++i)
	{
		for(UINT j = 0; j < ttexdesc.MipLevels; ++j)
		{
			D3D10_MAPPED_TEXTURE2D tmappedtex2d;
			ttexlist[i]->Map(j, D3D10_MAP_READ, 0, &tmappedtex2d);
            _obj_dx10_device->UpdateSubresource(ttexarray,D3D10CalcSubresource(j, i, ttexdesc.MipLevels),0, tmappedtex2d.pData, tmappedtex2d.RowPitch, 0);
			ttexlist[i]->Unmap(j);
		}
	}	

	D3D10_SHADER_RESOURCE_VIEW_DESC tviewdesc;
	tviewdesc.Format = ttexarraydesc.Format;
	tviewdesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2DARRAY;
	tviewdesc.Texture2DArray.MostDetailedMip = 0;
	tviewdesc.Texture2DArray.MipLevels = ttexarraydesc.MipLevels;
	tviewdesc.Texture2DArray.FirstArraySlice = 0;
	tviewdesc.Texture2DArray.ArraySize = tarraycount;

	ID3D10ShaderResourceView* ttexarray_rv= 0;
	if(FAILED(_obj_dx10_device->CreateShaderResourceView(ttexarray, &tviewdesc, &ttexarray_rv)))
		return NULL;

	ttexarray->Release();
	ttexarray = NULL;

	for(UINT i = 0; i < tarraycount; ++i)
	{
		ttexlist[i]->Release();
		ttexlist[i] = NULL;
	}

	_list_tex_cache.push_back(parrayid);
	_list_tex_rv.push_back(ttexarray_rv);

	return ttexarray_rv;
}


